package graphics.system;
import graphics.effects.Compositor;
import graphics.system.VertexBufferObject.Drawmode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

import tools.Floatmath;
import tools.Log;
import tools.Point;
public final class GLTools {
	private static VertexBufferObject quad;
	private static VertexBufferObject quad_tex;
	private static VertexBufferObject circle;
	private static VertexBufferObject circle_line;
	private static VertexBufferObject quadsmooth;
	private static Texture fonttex;
	private static Texture noisetex;
	public static void init() {
		Point quadv[] = {new Point(-0.5f, -0.5f), new Point(-0.5f, 0.5f), new Point(0.5f, 0.5f), new Point(0.5f, -0.5f)};
		Point quadtex[] = {new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 0)};
		quad = new VertexBufferObject(quadv, Drawmode.POLYGON);
		quad_tex = new VertexBufferObject(quadv, Drawmode.POLYGON);
		quad_tex.setTexCoords(quadtex);
		quadsmooth = new VertexBufferObject(quadv, Drawmode.LINES_LOOP);
		// quadsmooth.setTexCoords(quadtex);
		Point circlev[] = new Point[60];
		Point circlevl[] = new Point[circlev.length - 1];
		circlev[0] = new Point(0, 0);
		float step = (Floatmath.PI * 2) / (float) (circlev.length - 1);
		float a = 0;
		for (int i = 1; i < circlev.length; i++) {
			circlev[i] = new Point(Floatmath.cos(a), Floatmath.sin(a));
			circlevl[i - 1] = new Point(Floatmath.cos(a), Floatmath.sin(a));
			a += step;
		}
		circle = new VertexBufferObject(circlev, Drawmode.TRIANGLE_FAN);
		circle_line = new VertexBufferObject(circlevl, Drawmode.LINES_LOOP);
		fonttex = TextureContainer.getTexture("fontmap2");
		noisetex = TextureContainer.getTexture("noise");
		// fonttex.setFilterNearest();
		Log.g("GLTools initialized");
	}
	public static void drawTexRect(Point pos, float w, float h, float angle, int texid, Color col) {
		drawTexRect(pos.x, pos.y, w, h, angle, texid, col);
	}
	public static void drawTexRect(float x, float y, float w, float h, float angle, int texid, Color col) {
		col.set();
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, texid);
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glPushMatrix();
		GL11.glTranslatef(x, y, 0);
		GL11.glRotatef(angle, 0, 0, 1);
		GL11.glScalef(w, h, 0);
		quad_tex.draw();
		GL11.glPopMatrix();
		GL11.glDisable(GL11.GL_TEXTURE_2D);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
	}
	public static void drawTexRectYmirror(Point p, float w, float h, float angle, int texid, Color col) {
		col.set();
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, texid);
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glPushMatrix();
		GL11.glTranslatef(p.x, p.y, 0);
		GL11.glRotatef(angle, 0, 0, 1);
		GL11.glScalef(w, -h, 0);
		quad_tex.draw();
		GL11.glPopMatrix();
		GL11.glDisable(GL11.GL_TEXTURE_2D);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
	}
	public static void drawTexRect(float x, float y, float w, float h, int texid) {
		drawTexRect(x, y, w, h, 0, texid, Color.white);
	}
	public static void drawText(float x, float y, String txt, Color c) {
		final float ts = 1.0f / 16.0f;
		final float fw = 10;
		final float lsx = 15;
		final float lsy = 15;
		GL11.glEnable(GL11.GL_COLOR_MATERIAL);
		char ctxt[] = txt.toCharArray();
		float tx, ty, cx;
		/*
		 * for(int i=0;i<ctxt.length;i++){ drawRect(new Point(x+i*fw,y).add(new Point(lsx/2,lsy/2)),lsx,lsy,0, new Color(1,1,1,0.1f)); }
		 */
		c.set();
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		fonttex.bind();
		GL11.glPushMatrix();
		GL11.glBegin(GL11.GL_QUADS);
		for (int i = 0; i < ctxt.length; i++) {
			tx = ((ctxt[i] % 16)) * ts;
			ty = ((ctxt[i] / 16) - 1) * ts;
			ty += (ctxt[i] / 16);
			cx = x + i * fw;
			GL11.glTexCoord2f(tx, ty + ts);
			GL11.glVertex2f(cx, y);
			GL11.glTexCoord2f(tx + ts, ty + ts);
			GL11.glVertex2f(cx + lsx, y);
			GL11.glTexCoord2f(tx + ts, ty);
			GL11.glVertex2f(cx + lsx, y + lsy);
			GL11.glTexCoord2f(tx, ty);
			GL11.glVertex2f(cx, y + lsy);
		}
		GL11.glEnd();
		GL11.glPopMatrix();
		GL11.glDisable(GL11.GL_TEXTURE_2D);
	}
	public static void setViewPort(int viewportx, int viewporty) {
		GL11.glViewport(0, 0, viewportx, viewporty);
	}
	public static void setUpMatrix2D(int x, int y) {
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, y, 0, x, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
	public static void reshape2D(float w, float h) {
		GL11.glViewport(0, 0, (int) w, (int) h);
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, w, 0, h, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
	public static void blurFB(Framebuffer f0, Framebuffer f1, int samples, float strength, float multi, float width, float height) {
		Compositor.blur.enable();
		Compositor.blur.setParami("colorMap", 0);
		GL11.glClearColor(0, 0, 0, 0);
		Compositor.blur.setParamf("multi", multi);
		Compositor.blur.setParamf("sw", 1.0f / width);
		Compositor.blur.setParamf("sh", 1.0f / height);
		for (int i = 0; i < samples; i++) {
			Point bldir = new Point(strength, strength * 0.1f).rotate((float) i * (Floatmath.PI * 0.25f) / (float) samples);
			Point bldirn = bldir.normal();
			Compositor.blur.setParamf("x", bldir.x);
			Compositor.blur.setParamf("y", bldir.y);
			f1.enable();
			f1.clear();
			f0.drawOnScreen(f1.xres / 2, f1.yres / 2, f1.xres, f1.yres);
			Compositor.blur.setParamf("x", bldirn.x);
			Compositor.blur.setParamf("y", bldirn.y);
			f0.enable();
			f0.clear();
			f1.drawOnScreen(f0.xres / 2, f0.yres / 2, f0.xres, f0.yres);
		}
		f0.disable();
		Compositor.blur.disable();
	}
	public static void drawRect(Point pos, float w, float h, float angle, Color c) {
		GL11.glPushMatrix();
		GL11.glTranslatef(pos.x, pos.y, 0);
		GL11.glRotatef(angle, 0, 0, 1);
		GL11.glScalef(w, h, 0);
		quad.drawAt(new Point(0, 0), 0, c);
		GL11.glEnable(GL11.GL_LINE_SMOOTH);
		quadsmooth.drawAt(Point.ZERO, 0, c);
		GL11.glPopMatrix();
	}
	public static void drawLine(Point s, Point e, Color c) {
		c.set();
		GL11.glEnable(GL11.GL_LINE_SMOOTH);
		GL11.glBegin(GL11.GL_LINES);
		GL11.glVertex2f(s.x, s.y);
		GL11.glVertex2f(e.x, e.y);
		GL11.glEnd();
	}
	public static void drawCircle(Point pos, float radius, float angle, Color c) {
		drawCircle(pos, radius, angle, c, false);
	}
	public static void drawCircle(Point pos, float radius, float angle, Color c, boolean drawcross) {
		GL11.glPushMatrix();
		GL11.glTranslatef(pos.x, pos.y, 0);
		GL11.glRotatef(angle, 0, 0, 1);
		GL11.glScalef(radius, radius, 0);
		circle.drawAt(new Point(0, 0), 0, c);
		if (drawcross) {
			new Color(0, 0, 0, 1).set();
			GL11.glEnable(GL11.GL_LINE_SMOOTH);
			GL11.glBegin(GL11.GL_LINES);
			GL11.glVertex2f(-0.5f, 0);
			GL11.glVertex2f(0.5f, 0);
			GL11.glVertex2f(0, 0.5f);
			GL11.glVertex2f(0, -0.5f);
			GL11.glEnd();
		}
		GL11.glPopMatrix();
	}
	public static void drawCircleLine(Point pos, float radius, float angle, Color c, boolean drawcross) {
		GL11.glPushMatrix();
		GL11.glEnable(GL11.GL_LINE_SMOOTH);
		GL11.glTranslatef(pos.x, pos.y, 0);
		GL11.glRotatef(angle, 0, 0, 1);
		GL11.glScalef(radius, radius, 0);
		circle_line.drawAt(Point.ZERO, 0, c);
		if (drawcross) {
			new Color(0, 0, 0, 1).set();
			GL11.glBegin(GL11.GL_LINES);
			GL11.glVertex2f(-0.5f, 0);
			GL11.glVertex2f(0.5f, 0);
			GL11.glVertex2f(0, 0.5f);
			GL11.glVertex2f(0, -0.5f);
			GL11.glEnd();
		}
		GL11.glPopMatrix();
	}
	public static void drawPoint(Point pos, Color color, float s) {
		GL11.glPointSize(s);
		color.set();
		GL11.glBegin(GL11.GL_POINTS);
		GL11.glVertex2f(pos.x, pos.y);
		GL11.glEnd();
	}
	public static void drawQuad(Point a, Point b, Point c, Point d, Color color) {
		color.set();
		GL11.glBegin(GL11.GL_QUADS);
		GL11.glVertex2f(a.x, a.y);
		GL11.glVertex2f(b.x, b.y);
		GL11.glVertex2f(c.x, c.y);
		GL11.glVertex2f(d.x, d.y);
		GL11.glEnd();
		GL11.glBegin(GL11.GL_LINE_LOOP);
		GL11.glVertex2f(a.x, a.y);
		GL11.glVertex2f(b.x, b.y);
		GL11.glVertex2f(c.x, c.y);
		GL11.glVertex2f(d.x, d.y);
		GL11.glEnd();
	}
	public static void drawRectWire(Point pos, float w, float h, float angle, Color c) {
		GL11.glPushMatrix();
		GL11.glTranslatef(pos.x, pos.y, 0);
		GL11.glRotatef(angle, 0, 0, 1);
		GL11.glScalef(w, h, 1);
		GL11.glEnable(GL11.GL_LINE_SMOOTH);
		quadsmooth.drawAt(Point.ZERO, 0, c);
		GL11.glPopMatrix();
	}
	public static void drawText(Point s, String text, Color textCol) {
		drawText(s.x, s.y, text, textCol);
	}
	public static void drawText(Point pos, String text, Color textCol, float size) {
		drawText(pos, text, textCol, size, size);
	}
	public static void drawText(Point pos, String text, Color textCol, float sx, float sy) {
		GL11.glPushMatrix();
		GL11.glTranslatef(pos.x, pos.y, 0);
		GL11.glScalef(sx, sy, 1);
		drawText(0, 0, text, textCol);
		GL11.glPopMatrix();
	}
	public static void drawLineLoop(Point[] v, Color color) {
		color.set();
		GL11.glEnable(GL11.GL_LINE_SMOOTH);
		GL11.glBegin(GL11.GL_LINE_LOOP);
		for (int i = 0; i < v.length; i++) {
			GL11.glVertex2f(v[i].x, v[i].y);
		}
		GL11.glEnd();
	}
}
